package com.service.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import com.service.bean.company.Company;
import com.service.bean.device.Vehicle;
import com.service.bean.oil.OilBean;
import com.service.bean.other.VehicleScalar;
import com.service.bean.signal.GpsSignal;
import com.service.cache.CacheManager;
import com.service.calculate.vehicle.ProcessPool;
import com.service.calculate.vehicle.SignalCreator;
import com.service.db.DbConnectionManager;
import com.service.db.PooledConnection;
import com.service.other.Logger;
import com.service.other.ServerConfig;
import com.service.scheduler.sched.SaveGpsSched;
import com.service.scheduler.sched.SaveWorkChangeSched;
import com.service.socket.protocol.CmdWord;
import com.service.socket.protocol.Conversion;
import com.service.socket.protocol.Packet;
import com.service.socket.protocol.Resolver;
import com.service.tools.Tools;
/****
 * 西湖市政数据补入
 * @author Administrator
 *
 */
public class DataRebornTestNew {
	
	public static void main(String[] args){
		// 从数据库中取出所有数据，从中筛选出西湖市政数据(companycode='014')
		System.out.println("starttime:" + new Date());
		intanceScheduler();
		Long starttime = System.currentTimeMillis();
		CacheManager.instance();
		Map<String, Vehicle> vehicleMap = CacheManager.instance().vehicleMap;
		String lastdate ="2016-06-05";
		String deldate ="2016-06-06";
		
		ArrayList<String> lst = new ArrayList<String>();
		lst.add("D:\\databak\\2016-06-05");
		lst.add("D:\\databak\\2016-06-06");
		
		ArrayList<String> lstDel = new ArrayList<String>();
		
		//错误数据（丢失数据的时间点后的数据） 删除
		for(Vehicle vehicle : vehicleMap.values()){
			if (!"014".equals(vehicle.company.code)) {
				String gpsno = vehicle.device.deviceNo;
				File file = new File(lst.get(0)+"\\"+gpsno+".txt");
				if (file.exists() && !lstDel.contains(vehicle.company.code)) {
					System.out.println("del:" + vehicle.company.code);
					lstDel.add(vehicle.company.code);
					deletesignalbydate(vehicle.company,deldate);
				}
			}			
		}
		
		//lastgps数据更新
		for(Vehicle vehicle : vehicleMap.values()){
			if (!"014".equals(vehicle.company.code)) {
				vehicle.lastGps = getLastGps(vehicle.equipmentId,vehicle.company,lastdate);
				if(vehicle.lastGps != null){
					vehicle.oilBean = new OilBean();			
					System.out.println("newlast=" + vehicle.lastGps.gpsTime);
				}
				
			}

		}
		
		Long endtime = System.currentTimeMillis();
		
		System.out.println((endtime - starttime)/1000);
		//启动数据恢复
		for(Vehicle vehicle : vehicleMap.values()){
			if (!"014".equals(vehicle.company.code)) {
				for(String filepath:lst){
					File file = new File(filepath+"\\"+vehicle.device.deviceNo+".txt");
					if (file.exists()){
						readFile(filepath+"\\"+vehicle.device.deviceNo+".txt");
					}
							
					
				}
				
			}
			
		}
		
		System.out.println("endtime:" + new Date());
	}

	private static void intanceScheduler() {
		new SaveGpsSched().init();
		new SaveWorkChangeSched().init();
		for (Scheduler sched : CacheManager.instance().schedMap.values()) {
			try {
				sched.start();
			} catch (SchedulerException e) {
				Logger.err(e);
			}
		}
	}

	public static void readFile(String filePath) {
		try {
			String encoding = "GBK";
			Packet packet = null;
			File file = new File(filePath);
			if (file.isFile() && file.exists()) { // 判断文件是否存在
				InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
				BufferedReader bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				while ((lineTxt = bufferedReader.readLine()) != null) {
					//解析packet
					String s = lineTxt.substring(2, lineTxt.length() - 2);
					byte[] bytes = Conversion.dataEncode(Conversion.hexStringToBytes(s.toString()));	
					packet = Resolver.parsePacket(bytes);
					if(packet!=null && packet.cmdType.equals("B0")&&Integer.parseInt(packet.length)>1000){
						
						parseDataArea(packet);
					}
				}
				read.close();
			} else {
				System.out.println("找不到指定的文件");
			}
		} catch (Exception e) {
			System.out.println("读取文件内容出错");
			e.printStackTrace();
		}

	}
	
	private static VehicleScalar vehicleScalar = null;
	private static Vehicle vehicle = null;
	
	private static void parseDataArea(Packet packet) {
		if(!CacheManager.instance().scalarCalers.containsKey(packet.getDeviceNo())){
			CacheManager.instance().scalarCalers.put(packet.getDeviceNo(), new VehicleScalar());
		}
		vehicleScalar = CacheManager.instance().scalarCalers.get(packet.getDeviceNo());	
		if (CacheManager.instance().vehicleMap.containsKey(packet.getDeviceNo())) {
			vehicle = CacheManager.instance().getVehicle(packet.getDeviceNo());							
		}
		
		if (vehicle == null) {
			 // Gps未绑定车辆
			packet.status = CmdWord.STATUS_FAIL;
			packet.dataArea = null;
//			SendCommand.replyDtu(channel, packet);
			Logger.err("device [" + packet.getDeviceNo() + "] process fail : vehicle no bind");
			return;
		}
		if (!packet.isCrcValid()) {
			// CRC校验失败
			packet.status = CmdWord.STATUS_FAIL;
			packet.dataArea = null;
//			SendCommand.replyDtu(channel, packet);
			Logger.err("device [" + packet.getDeviceNo() + "] process fail on [CrcValid]:" + packet.isCrcValid());
			Logger.err(packet.toString());
			return;
		}


		
		// 获得signal对象
		SignalCreator creator = new SignalCreator(packet.dataArea, packet.getDeviceNo());			
		GpsSignal signal = creator.createSignal();
		
		//新增，如果当日数据已经存在，那么不进行处理
		if(!signal.gpsTime.after(vehicle.lastGps.gpsTime)){
			return;
		}
		
		
		if (signal.lat == 0 || signal.lng == 0) {
			// 无效数据也提供给前端
			signal.gpsTime = new Date();
			vehicle.setLastGps_lastest(signal);		
			Logger.err("device [" + packet.getDeviceNo() + "] process fail : lat or lng = 0");
			return;
		}

		long longTime = 0;
		if(vehicle.lastGps_Received != null){
			longTime = Math.abs(Tools.getTimeLong(signal.gpsTime, vehicle.lastGps_Received.gpsTime));
		}
		//数据区放入队列
		CacheManager.instance().getSignalQueue(packet.getDeviceNo()).offer(signal);			
		//确认实时数据件数并进行计算
		if(checkRealTimeWithScalarCal(packet.getDeviceNo(),signal.dataTypes,longTime)){
			ProcessPool.scalarCal(vehicleScalar, packet.getDeviceNo());
		}else{
			vehicle.setLastGps_lastest(signal);
		}
		
		//终端发过来的最新数据，用来计算和上一条的间隔时间
		vehicle.lastGps_Received = signal;
		}
	

	
/**
 * 判定是否启动正式计算
 * @param deviceNo
 * @param dataTypes <pre> 0：历史数据 </br>1：实时数据</pre>
 * @param longTime
 */
public static boolean checkRealTimeWithScalarCal(String deviceNo, Integer dataTypes, long longTime) {
	
	synchronized(vehicleScalar){
		//判断数据类型（0：历史数据， 1：实时数据）|| 如果和上一条间隔时间超过60秒（计数清0）
		if(dataTypes==0 || longTime >  ServerConfig.instance().intervaltime){
			//出现历史数据，累计数清0
			vehicleScalar.realAdd =0;
		}else{
			//出现实时数据，开始累计（累计数不超过3）
			if (vehicleScalar.realAdd < 3){
				vehicleScalar.realAdd++;
			}				
		}
		//连续实时数据=3件的场合，启动计算
		if(vehicleScalar.realAdd == 3){
			return true;
		}			
	}
	return false;
}

	public static void removeFile(String url ,String gpsno) {
		File file = new File(url);
		if (file.exists()) {
			boolean d = file.delete();
			if (d) {
				System.out.print("车辆:"+gpsno+"删除成功！\n");
			} else {
				System.out.print("车辆:"+gpsno+"删除失败！");
			}
		}
	}
	
	public static GpsSignal getLastGps(String EquipmentId,Company company,String date){
		GpsSignal signal = null;
		PooledConnection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs= null;
		String strSQL = "select top 1 * from crc_GPSSignal where EquipmentId = ?  and GPSStatus = 1 and  convert(varchar(10),gpstime,23)<=?"; 
		try{
			con = DbConnectionManager.getConnection(company);
			pstmt = con.prepareStatement(strSQL);
			pstmt.setString(1, EquipmentId);
			pstmt.setString(2, date);
			long x = System.currentTimeMillis();
			rs = pstmt.executeQuery();
			System.out.println("getLastGps " + (System.currentTimeMillis() - x));
			if (rs.next()) {
				signal = new GpsSignal();
				Field[] field = signal.getClass().getFields();
				for(Field f : field){
					try {
						f.setAccessible(true);
						
						switch (f.getType().getName()) {
							case "java.lang.String":								
								if (rs.getString(f.getName()) != null){
									f.set(signal, rs.getString(f.getName()));
								}
								break;
							case "java.util.Date":
								if (rs.getTimestamp(f.getName()) != null){
									f.set(signal, rs.getTimestamp(f.getName()));
								}

								break;
							case "double":
								if (rs.getDouble(f.getName()) != 0){
									f.set(signal, rs.getDouble(f.getName()));
								}

								break;
							case "int":
								if (rs.getInt(f.getName()) != 0){
									f.set(signal, rs.getInt(f.getName()));
								}
								break;
							default:
								break;
						}

					}catch (Exception e) {
//						System.out.println(f.getName());
					}
				}
			}
		}catch(Exception e){
			Logger.err(e);
		}finally{
			try {
				if(rs!=null && !rs.isClosed()){
					rs.close();
				}
				if(pstmt!=null && !pstmt.isClosed()){
					pstmt.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				Logger.err(e);
			}
		}
		return signal;
	}
	
	
	/**
	 * 查出每辆车最早的一条数据
	 * date：查询时间
	 */
	public static GpsSignal getGps(String gpsno ,Company company, String date){
		GpsSignal signal = null;
		PooledConnection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs= null;
		String sql = "select top 1  gpstime from crc_GPSSignal  where gpsno=? "
				+ "and convert(varchar(10),gpstime,23)=? "
				+ "order by gpstime";
		try{
			con = DbConnectionManager.getConnection(company);
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, gpsno);
			pstmt.setString(2, date);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				signal = new GpsSignal();
				signal.gpsTime = rs.getTimestamp("gpstime");
			}
		}catch(Exception e){
			Logger.err(e);
		}finally{
			try {
				if(rs!=null && !rs.isClosed()){
					rs.close();
				}
				if(pstmt!=null && !pstmt.isClosed()){
					pstmt.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				Logger.err(e);
			}
		}
		return signal;
	}
	
	/**
	 * 数据删除,以公司为单位
	 * @param company
	 */
	public static void deletesignalbydate(Company company, String date) {

		PooledConnection con = null;
		Statement pstmt = null;
		try {

			con = DbConnectionManager.getConnection(company);
			pstmt = con.prepareStatement();
			String sql = "delete from  [crc_GPSSignal] where convert(varchar(10),gpstime,23)= '" + date + "' " ;
			pstmt.execute(sql); 
			
			
		} catch (SQLException e) {
			Logger.err(e);
		} finally {
			try {
				if(pstmt!=null && !pstmt.isClosed()){
					pstmt.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				Logger.err(e);
			}
		}
	}
}
